﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Silverlight.Testing;
using System8ToyMC;
using System.Windows.Controls;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Automation;
using System.Collections.ObjectModel;
using System.Linq;

namespace t_System8ToyMCControls
{
    /// <summary>
    /// Test the save/load control
    /// </summary>
    [TestClass]
    public class t_SaveLoad : PresentationTest
    {
        bool failed = false;

        SaveLoad _val;

        Button _save, _load;

        AutoCompleteBox _enter;

        ObservableCollection<string> _stuffToSet;

        [TestInitialize]
        public void DoInit()
        {
            try
            {
                _val = new SaveLoad();
                _stuffToSet = new ObservableCollection<string>();
                _val.SavedNames = _stuffToSet;

                _save = _val.FindName("SaveButton") as Button;
                _load = _val.FindName("LoadButton") as Button;
                _enter = _val.FindName("DatasetName") as AutoCompleteBox;
            }
            catch
            {
                failed = true;
                throw;
            }
        }

        [TestMethod]
        public void TestCtor()
        {
            Assert.IsFalse(failed);
        }

        [TestMethod]
        public void TestAllThere()
        {
            Assert.IsNotNull(_save, "Missing save button");
            Assert.IsNotNull(_load, "Missing load button");
            Assert.IsNotNull(_enter, "Missing data set name");
        }

        [TestMethod]
        [Asynchronous]
        [ExpectedException(typeof(ElementNotEnabledException))]
        public void TestLoadNullInitial()
        {
            ButtonAutomationPeer bp = new ButtonAutomationPeer(_load);
            ButtonAutomationPeer buttonPeer = new ButtonAutomationPeer(_load);
            IInvokeProvider buttonInvoker = (IInvokeProvider)buttonPeer;
            EnqueueCallback(() => TestPanel.Children.Add(_val));
            EnqueueCallback(() => buttonInvoker.Invoke());
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        [ExpectedException(typeof(ElementNotEnabledException))]
        public void TestSaveNullInitial()
        {
            ButtonAutomationPeer bp = new ButtonAutomationPeer(_save);
            ButtonAutomationPeer buttonPeer = new ButtonAutomationPeer(_load);
            IInvokeProvider buttonInvoker = (IInvokeProvider)buttonPeer;
            EnqueueCallback(() => TestPanel.Children.Add(_val));
            EnqueueCallback(() => buttonInvoker.Invoke());
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void TestSaveButtonEnabled()
        {
            AutoCompleteBoxAutomationPeer autopeer = new AutoCompleteBoxAutomationPeer(_enter);
            IValueProvider val = (IValueProvider)autopeer;
            ButtonAutomationPeer buttonPeer = new ButtonAutomationPeer(_save);
            IInvokeProvider buttonInvoker = (IInvokeProvider)buttonPeer;

            EnqueueCallback(() => TestPanel.Children.Add(_val));
            EnqueueCallback(() => val.SetValue("Bogus"));
            EnqueueCallback(() => buttonInvoker.Invoke());
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void TestLoadButtonEnabled()
        {
            AutoCompleteBoxAutomationPeer autopeer = new AutoCompleteBoxAutomationPeer(_enter);
            IValueProvider val = (IValueProvider)autopeer;
            ButtonAutomationPeer buttonPeer = new ButtonAutomationPeer(_load);
            IInvokeProvider buttonInvoker = (IInvokeProvider)buttonPeer;

            EnqueueCallback(() => TestPanel.Children.Add(_val));
            EnqueueCallback(() => val.SetValue("Bogus"));
            EnqueueCallback(() => buttonInvoker.Invoke());
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void TestSaveButtonCallback()
        {
            bool called = false;
            string whatIsTheName = "";
            _val.SaveData += name => { called = true; whatIsTheName = name; };
            AutoCompleteBoxAutomationPeer autopeer = new AutoCompleteBoxAutomationPeer(_enter);
            IValueProvider val = (IValueProvider)autopeer;
            ButtonAutomationPeer buttonPeer = new ButtonAutomationPeer(_save);
            IInvokeProvider buttonInvoker = (IInvokeProvider)buttonPeer;

            EnqueueCallback(() => TestPanel.Children.Add(_val));
            EnqueueCallback(() => val.SetValue("Bogus"));
            EnqueueCallback(() => buttonInvoker.Invoke());
            EnqueueDelay(10);
            EnqueueCallback(() => Assert.IsTrue(called, "Expected the call to complete!"));
            EnqueueCallback(() => Assert.AreEqual("Bogus", whatIsTheName, "Expected the load to work!"));
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void TestLoadButtonCallbackWithBogusName()
        {
            bool called = false;
            string whatIsTheName = "";

            _val.LoadSavedData += new Action<string>(name => { called = true; whatIsTheName = name; });
            AutoCompleteBoxAutomationPeer autopeer = new AutoCompleteBoxAutomationPeer(_enter);
            IValueProvider val = (IValueProvider)autopeer;
            ButtonAutomationPeer buttonPeer = new ButtonAutomationPeer(_load);
            IInvokeProvider buttonInvoker = (IInvokeProvider)buttonPeer;

            EnqueueCallback(() => TestPanel.Children.Add(_val));
            EnqueueCallback(() => val.SetValue("Bogus"));
            EnqueueCallback(() => buttonInvoker.Invoke());
            EnqueueDelay(10);
            EnqueueCallback(() => Assert.IsFalse(called, "Expected the call to complete!"));
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void TestLoadButtonCallbackWithGoodName()
        {
            bool called = false;
            string whatIsTheName = "";
            _stuffToSet.Add("Bogus");

            _val.LoadSavedData += name => { called = true; whatIsTheName = name; };
            AutoCompleteBoxAutomationPeer autopeer = new AutoCompleteBoxAutomationPeer(_enter);
            IValueProvider val = (IValueProvider)autopeer;
            ButtonAutomationPeer buttonPeer = new ButtonAutomationPeer(_load);
            IInvokeProvider buttonInvoker = (IInvokeProvider)buttonPeer;

            EnqueueCallback(() => TestPanel.Children.Add(_val));
            EnqueueCallback(() => val.SetValue("Bogus"));
            EnqueueCallback(() => buttonInvoker.Invoke());
            EnqueueDelay(10);
            EnqueueCallback(() => Assert.IsTrue(called, "Expected the call to complete!"));
            EnqueueCallback(() => Assert.AreEqual("Bogus", whatIsTheName, "Expected callback name different!"));
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void TestDropdown()
        {
            _stuffToSet.Add("Bogus1");
            _stuffToSet.Add("Bogus2");

            AutoCompleteBoxAutomationPeer autopeer = new AutoCompleteBoxAutomationPeer(_enter);
            IValueProvider val = (IValueProvider)autopeer;
            EnqueueCallback(() => TestPanel.Children.Add(_val));
            EnqueueCallback(() => val.SetValue("B"));
            EnqueueConditional(() => _enter.SearchText == "B");
            //EnqueueCallback(() => Assert.IsTrue(dropDownThere, "Expected the drop down to open!"));
            /// Don't know how to code this up right now! Ops!
            EnqueueTestComplete();
        }

        [TestMethod]
        public void TestItemSourceBinding()
        {
            _stuffToSet.Add("hithere");

            Assert.IsNotNull(_enter.ItemsSource, "Item source is null");
            int count = 0;
            foreach (var i in _enter.ItemsSource)
            {
                count += 1;
            }
            Assert.AreEqual(1, count, "Expected 1 item in the source!");
        }
    }
}